package com.xy.job.executor.log.logger

internal class Log4jLogger(
    val logger: org.apache.log4j.Logger
) : Logger {

    override fun debug(msg: String?) {
        logger.debug(msg)
    }

    override fun debug(msg: String?, throwable: Throwable?) {
        logger.debug(msg, throwable)
    }

    override fun debug(msg: String?, vararg args: Any?) {
        val message: String = formatString(msg!!, args)
        if (args.lastOrNull() is Throwable) {
            logger.debug(message, args.last() as Throwable)
        } else {
            logger.debug(message)
        }
    }

    override fun info(msg: String?) {
        logger.info(msg)
    }

    override fun info(msg: String?, throwable: Throwable?) {
        logger.info(msg, throwable)
    }

    override fun info(msg: String?, vararg args: Any?) {
        val message: String = formatString(msg!!, args)
        if (args.lastOrNull() is Throwable) {
            logger.info(message, args.last() as Throwable)
        } else {
            logger.info(message)
        }
    }

    override fun warn(msg: String?) {
        logger.warn(msg)
    }

    override fun warn(msg: String?, throwable: Throwable?) {
        logger.warn(msg, throwable)
    }

    override fun warn(msg: String?, vararg args: Any?) {
        val message: String = formatString(msg!!, args)
        if (args.lastOrNull() is Throwable) {
            logger.warn(message, args.last() as Throwable)
        } else {
            logger.warn(message)
        }
    }

    override fun error(msg: String?) {
        logger.error(msg)
    }

    override fun error(msg: String?, throwable: Throwable?) {
        logger.error(msg, throwable)
    }

    override fun error(msg: String?, vararg args: Any?) {
        val message: String = formatString(msg!!, args)
        if (args.lastOrNull() is Throwable) {
            logger.error(message, args.last() as Throwable)
        } else {
            logger.error(message)
        }
    }

    private fun formatString(message: String, vararg args: Any): String {
        val builder = StringBuilder()
        var argsIndex = 0
        var index = 0
        while (index < message.length) {
            if (message[index] == '{' && index + 1 < message.length && message[index + 1] == '}' && argsIndex < args.size) {
                builder.append(args[argsIndex])
                ++index
                ++argsIndex
            } else {
                builder.append(message[index])
            }
            ++index
        }
        return builder.toString()
    }
}